package com.j.lemon.learn.basic.lambda;

import com.j.lemon.learn.basic.object.justtest.Employee;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Test1 {

    List<String> list = Arrays.asList("8", "1", "2", "2", "3", "3", "4");
    List<String> list1 = Arrays.asList("a", "b", "c", "d", "e", "f");
    List<String> list2 = Arrays.asList("wedasdqwe", "qweqweqweqe", "c", "dee", "eddd", "1");


    @Test
    void test() {
        Stream<Integer> integerStream = list.stream().filter(s -> Integer.valueOf(s) > 2).collect(Collectors.toList()).stream().map(str -> Integer.valueOf(str) * 100).distinct();
        Iterator<Integer> iterator = integerStream.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    /**
     * 创建stream的四种方式
     */
    @Test
    void create() {
        //1直接丶
        Stream<String> stream = list.stream();
        //2创建一个空的stream
        Stream<Object> empty = Stream.empty();
        //3创建一个无限流，每一个元素都是'key'
        Stream<String> generate = Stream.generate(() -> "key");
        //4创建一个无限流，元数都是0-1的随机数(包含0)
        Stream<Double> generate1 = Stream.generate(Math::random);
        //创建一个无限流，元素为：将函数（第二个参数）应用到第一个参数的结果,循环，所以第一个参数是会变化的
        Stream<Integer> iterate = Stream.iterate(0, n -> ++n);

        System.out.println(stream.count());

        System.out.println(empty.count());


        //下面这三种会一直执行
//        System.out.println(generate.count());
//        System.out.println(generate1.count());
//        System.out.println(iterate.count());
        Stream<Integer> limit = iterate.limit(100);
        limit.forEach(System.out::println);
    }

    /**
     * 文件相关操作
     *
     * @throws IOException
     */
    @Test
    void file() throws IOException {
        String s = new String(Files.readAllBytes(Paths.get("/Users/lijunjun/work/file.log")), StandardCharsets.UTF_8);
        Stream<String> s1 = Stream.of(s.split(","));
        s1.forEach(System.out::println);

        Stream<String> lines = Files.lines(Paths.get("/Users/lijunjun/work/file.log"), StandardCharsets.UTF_8);
        lines.forEach(System.out::println);
    }


    /**
     * 抽取流和连接流 limit,skip,concat
     */
    @Test
    void calculate() {
        //创建一个无限流
        Stream<Integer> iterate = Stream.iterate(1, n -> ++n);
        Stream<Integer> iterate1 = Stream.iterate(1, n -> n = n + 2);
        //截取100个元素
        Stream<Integer> limit = iterate.limit(100);
        //跳过前十个元素
        Stream<Integer> skip10 = limit.skip(10);
        //跳过前80个元素
        Stream<Integer> skip80 = iterate1.limit(100).skip(80);

        //连接两个流(流的元素类型必须一样)
        Stream<Integer> concat = Stream.concat(skip10, skip80);
        concat.forEach(System.out::println);
    }

    /**
     * 排序
     */
    @Test
    void sort() {
        Stream<String> sorted = list.stream().sorted(Comparator.comparing(s -> Integer.valueOf(String.valueOf(s))).reversed());
        sorted.forEach(System.out::println);
    }

    /**
     * 简单约简
     */
    @Test
    void simple() {
        Optional<String> max = list.stream().max(Comparator.comparing(s -> Integer.valueOf(String.valueOf(s))));
        String s = max.get();
        System.out.println(s);

        List<Double> list = new ArrayList<>();
        Optional<Double> min = list.stream().min(Comparator.comparingDouble(Double::doubleValue));
        System.out.println(min.isPresent());

    }

    /**
     * 收集
     */
    @Test
    void toMap() {
        Employee e1 = new Employee(18, "zhangsan");
        Employee e2 = new Employee(20, "lisi");
        Employee e3 = new Employee(13, "wangwu");
        Employee e4 = new Employee(13, "zhaoliu");

        //将多个元素收集为map
        Stream<Employee> employees = Stream.of(e1, e2, e3);
        Map<Integer, String> collect = employees.collect(Collectors.toMap(Employee::getAge, Employee::getName));
        collect.forEach((k, v) -> System.out.println(k + ":" + v));

//        Map<Integer, Employee> collect1 = employees.collect(Collectors.toMap(Employee::getAge, Function.identity()));


        //当出现key重复时，默认会抛出IllegalStateException，所以需要第三个参数，来指定当key重复时value要如何处理
//        Stream<Locale> availableLocales = Stream.of(Locale.getAvailableLocales());
//        Map<String, String> collect2 = availableLocales.collect(Collectors.toMap(Locale::getDisplayName, l -> l.getDisplayLanguage(l), (exist, newValue) -> exist));
//        collect2.forEach((k,v)-> System.out.println(k+":"+v));

        //将国家的所以语言收集为map
//        Stream<Locale> availableLocales1 = Stream.of(Locale.getAvailableLocales());
//        Map<String, Set<String>> collect1 = availableLocales1.collect(Collectors.toMap(Locale::getDisplayCountry, locale -> Collections.singleton(locale.getDisplayLanguage()), (exist, newValue) -> {
//            Set<String> set = new HashSet<>(exist);
//            set.addAll(newValue);
//            return set;
//        }));
//        collect1.forEach((k,v)-> System.out.println(k+':'+v));
//
//        Stream<Locale> availableLocales = Stream.of(Locale.getAvailableLocales());
//        Map<String, List<Locale>> collect2 = availableLocales.collect(Collectors.groupingBy(Locale::getDisplayCountry));
//        collect2.forEach((k,v)-> System.out.println(k+':'+v));

//        Stream<Locale> availableLocales2 = Stream.of(Locale.getAvailableLocales());
//        Map<String, List<String>> collect3 = availableLocales2.collect(Collectors.groupingBy(Locale::getDisplayCountry, Collectors.mapping(Locale::getDisplayLanguage, Collectors.toList())));
////        collect3.forEach((k,v)-> System.out.println(k+':'+v));
//
//
//        Stream<Locale> availableLocales = Stream.of(Locale.getAvailableLocales());
//        Map<Boolean, List<Locale>> en = availableLocales.collect(Collectors.partitioningBy(locale -> locale.getLanguage().equals("en")));
//        List<Locale> locales = en.get(true);
//        locales.forEach(locale -> System.out.println(locale.getDisplayName()));

//        Stream<Locale> availableLocales = Stream.of(Locale.getAvailableLocales());
//        Map<String, Set<String>> collect1 = availableLocales.collect(Collectors.toMap(Locale::getDisplayCountry, locale -> Collections.singleton(locale.getDisplayLanguage()),(a,b)->{
//            Set<String> set = new HashSet<>(a);
//            set.addAll(b);
//            return set;
//        }));
//        collect1.forEach((k,v)-> System.out.println(k+":"+v));

        Stream<Locale> availableLocales = Stream.of(Locale.getAvailableLocales());
        Map<String, List<String>> collect1 = availableLocales.collect(Collectors.groupingBy(Locale::getDisplayCountry, Collectors.mapping(Locale::getDisplayLanguage, Collectors.toList())));
        collect1.forEach((k,v)-> System.out.println(k+":"+v));

    }

    /**
     * 基本类型流
     */
    @Test
    void jibenleixing(){
        IntStream intStream = IntStream.of(23,1,24,546,24,5,68,5);
        IntStream sorted = intStream.sorted();
        sorted.forEach(System.out::println);
    }

    @Test
    void chongfu() {
        Map<Long, String> map = new HashMap<>();
        map.put(1L, "haha");
        map.put(2L, "haha");
        map.put(3L, "hehe");
        map.put(4L, "123");
        map.put(5L, "asd");
        map.put(6L, "haha");
        map.put(7L, "hehe");
        map.put(8L, "123");
        map.put(9L, "asd");




    }


}
